/**
 * @file snmp.h
 * @author weizhou
 * @brief SNMP Protocol
 * @version 0.1
 * @date 2024-03-11
 * 
 * @copyright Copyright (c) 2024 HYST Team
 * 
 */



#ifndef __SNMP_H__
#define __SNMP_H__



#include "qe_def.h"
#include "qe_string.h"
#include "qe_list.h"



#define SNMP_V1                     (0)

#define SNMP_COMMUNITY              "public\0"
#define SNMP_COMMUNITY_SIZE         qe_strlen(SNMP_COMMUNITY)

#define SNMP_PDU_GET_REQUEST        0xA0
#define SNMP_PDU_GET_NEXT_REQUEST   0xA1
#define SNMP_PDU_GET_RESPONSE       0xA2
#define SNMP_PDU_SET_REQUEST        0xA3

#define SNMP_DTYPE_INTEGER          0x02
#define SNMP_DTYPE_OCTET_STRING     0x04
#define SNMP_DTYPE_NULL_ITEM        0x05
#define SNMP_DTYPE_OBJ_ID           0x06
#define SNMP_DTYPE_SEQUENCE         0x30
#define SNMP_DTYPE_SEQUENCE_OF      SNMP_DTYPE_SEQUENCE
#define SNMP_DTYPE_COUNTER          0x41
#define SNMP_DTYPE_GAUGE            0x42
#define SNMP_DTYPE_TIME_TICKS       0x43
#define SNMP_DTYPE_OPAQUE           0x44

#define SNMP_OID_MAX                12
#define SNMP_STRING_MAX             128

#define SNMP_NO_ERROR               0
#define SNMP_ERROR_TOO_BIG          1
#define SNMP_ERROR_NO_SUCH_NAME     2
#define SNMP_ERROR_BAD_VALUE        3
#define SNMP_ERROR_READ_ONLY        4
#define SNMP_ERROR_GEN              5


typedef qe_ret (*snmp_get_func)(void *, int *);
typedef qe_ret (*snmp_set_func)(void *, int);


typedef struct
{
    qe_uint  size;
    qe_uint  index;
    qe_u8    buf[0];
} snmp_message;

typedef struct
{
    qe_u8 *s;      /* start position */
    qe_u8 *v;      /* value position */
    qe_u8 *n;      /* next start position */
    qe_uint len;
    qe_u8   dtype;
    qe_uint integer;
} snmp_tlv;

typedef struct
{
    snmp_tlv seq;
    snmp_tlv key;
    snmp_tlv val;
    qe_list list;
} snmp_kv;

typedef struct 
{
    qe_u8 oid_len;
    qe_u8 oid[SNMP_OID_MAX];
    qe_u8 dtype;
    qe_uint dlen;
    union {
        char string[SNMP_STRING_MAX];
        qe_u32 integer;
    } v;
    snmp_get_func get;
    snmp_set_func set;
} snmp_data_entry;

typedef struct
{
    snmp_tlv top;
    snmp_tlv version;
    snmp_tlv community;
    snmp_tlv request;
    snmp_tlv request_id;
    snmp_tlv error_status;
    snmp_tlv error_index;
    snmp_tlv sequence;
    qe_list values;
    int erridx;
    int errsts;
    qe_u8 request_type;
    qe_uint num_entrys;
    snmp_data_entry *entrys;
} snmp_parser;



qe_ret snmp_message_parse(snmp_parser *parser, snmp_message *msg);
qe_ret snmp_package_response(snmp_parser *parser, snmp_message *msg);
snmp_message *snmp_message_new(qe_uint size);

#endif /* __SNMP_H__ */